//
//  HPieChart.swift
//  Time
//
//  Created by hushaohua on 1/28/17.
//  Copyright © 2017 init. All rights reserved.
//

import UIKit

class HPieChartConfiguration : HChartViewConfiguration{
    var keyColor:UIColor = UIColor.gray;
    var valueColor:UIColor = UIColor.lightGray;
    var keyValueFont:UIFont = UIFont.systemFont(ofSize: 9, weight: .light);
    var keyContentEdge:UIEdgeInsets = UIEdgeInsetsMake(1, 6, 1, 6);
    var keyRectWidth:CGFloat = 20;
    var chartKeySpace:CGFloat = 10;
}

class HPieChartView: UIView {
    
    lazy var configuration:HPieChartConfiguration = {
        var config = HPieChartConfiguration();
        return config;
    }();
    
    var chartItems:[HPieChartItem]?{
        didSet{
            self.getSumValue();
            self.getRadiusCenter();
            self.getChartPointAngles();
            self.getKeyRects();
            self.getChartColors();
            self.setNeedsDisplay();
        }
    }
    lazy var drawableItems:[HPieChartItem] = {
        var items = [HPieChartItem]();
        return items;
    }();
    
    var sumValue:Int64 = 0;
    func getSumValue(){
        self.sumValue = 0;
        for chart in self.chartItems! {
            self.sumValue += chart.value;
        }
    }
    var pieCenter:CGPoint?;
    var radius:CGFloat?;
    func diameter() -> CGFloat{
        if (self.radius != nil){
            return 2 * self.radius!;
        }
        return 0;
    }
    func getRadiusCenter(){
        var center:CGPoint = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height / 2);
        if (self.bounds.width > self.bounds.height){
            center.x = self.bounds.height / 2;
            self.radius = self.bounds.height / 2;
        }else{
            center.y = self.bounds.width / 2;
            self.radius = self.bounds.width / 2;
        }
        self.pieCenter = center;
    }
    
    func getChartColors(){
        let colors = UIColor.pieChartColors(self.drawableItems.count);
        for index in 0...(self.drawableItems.count - 1) {
            let chart = self.drawableItems[index];
            chart.color = colors[index];
        }
    }
    
    func getChartPointAngles() -> Void {
        self.drawableItems.removeAll();
        var startPoint:CGPoint = CGPoint(x: self.center.x + self.radius!, y: self.radius!);
        var startAngle:CGFloat = 0;
        let otherChart:HPieChartItem = HPieChartItem();
        otherChart.key = "其他";
        for arcItem in self.chartItems! {
            let percent = CGFloat(arcItem.value) / CGFloat(self.sumValue);
            let endAngle = startAngle + percent * CGFloat(Double.pi * 2);
            arcItem.startPoint = startPoint;
            arcItem.startAngle = startAngle;
            arcItem.endAngle = endAngle;
           
            let startX:CGFloat = cos(endAngle) * self.radius! + self.radius!;
            let startY:CGFloat = sin(endAngle) * self.radius! + self.radius!;
            if ((abs(Int32(startX - startPoint.x)) >= 1 && abs(Int32(startY - startPoint.y)) >= 1) || ((endAngle - startAngle) > CGFloat(Double.pi / 2))){
                startAngle = endAngle;
                self.drawableItems.append(arcItem);
                startPoint = CGPoint(x: startX, y: startY);
            }else{
                otherChart.value += arcItem.value;
            }
        }
        if (otherChart.value > 0){
            let lastChart = self.drawableItems.last;
            otherChart.startAngle = lastChart!.endAngle;
            otherChart.endAngle = CGFloat(Double.pi * 2);
            let startX:CGFloat = cos(lastChart!.endAngle) * self.radius! + self.radius!;
            let startY:CGFloat = sin(lastChart!.endAngle) * self.radius! + self.radius!;
            otherChart.startPoint = CGPoint(x:startX, y:startY);
            self.drawableItems.append(otherChart);
            otherChart.valueString = otherChart.value.analysisDurationStringBySeconds();
        }
    }
    
    func getKeyRects() {
        var keysHeight:CGFloat = 0;
//        var maxWidth:CGFloat = 0;
        for chart in self.drawableItems {
            let string:String = "\(chart.key) \(chart.valueString)";
            let nsString:NSString = NSString(string: string);
            let size = nsString.size(withAttributes: [NSAttributedStringKey.font : self.configuration.keyValueFont]);
            chart.keyRect.size.width = size.width + 1;
            chart.keyRect.size.height = size.height + self.configuration.keyContentEdge.top + self.configuration.keyContentEdge.bottom;
            keysHeight += chart.keyRect.size.height;
//            if (chart.keyRect.size.width > maxWidth){
//                maxWidth = chart.keyRect.size.width;
//            }
        }
        var offsetY = (self.bounds.height - keysHeight) / 2;
        var offsetX = self.diameter() + self.configuration.chartKeySpace;
        if (offsetY < 0){
            offsetY = 0
        }
        
//        if (offsetX + self.configuration.keyRectWidth + self.configuration.keyContentEdge.left + maxWidth > self.bounds.width){
//            maxWidth = self.bounds.width - offsetX - self.configuration.keyRectWidth - self.configuration.keyContentEdge.left;
//        }
        var maxWidth:CGFloat = 0;
        for chart in self.drawableItems {
            chart.keyColorRect.origin.x = offsetX;
            chart.keyColorRect.origin.y = offsetY;
            chart.keyColorRect.size.width = self.configuration.keyRectWidth;
            chart.keyColorRect.size.height = chart.keyRect.size.height;
            chart.keyRect.origin.x = chart.keyColorRect.maxX + self.configuration.keyContentEdge.left;
            chart.keyRect.origin.y = offsetY;
            if (chart.keyRect.width > maxWidth){
                maxWidth = chart.keyRect.width;
            }
            offsetY = chart.keyRect.maxY;
            if (offsetY + chart.keyColorRect.size.height > self.bounds.height){
                offsetY = 0;
                offsetX = chart.keyRect.origin.x + maxWidth + 2;
            }
        }
    }
    
    override func draw(_ rect: CGRect) {
        super.draw(rect);
        self.drawArcs();
    }
    
    func drawBackground() -> Void {
        let context:CGContext = UIGraphicsGetCurrentContext()!;
        context.beginPath();
        context.addRect(self.bounds);
        context.closePath();
        self.backgroundColor!.setFill();
        context.drawPath(using: CGPathDrawingMode.fill);
    }
    
    func drawArcs() -> Void {
        let context:CGContext = UIGraphicsGetCurrentContext()!;
        for chart in self.drawableItems {
            context.beginPath();
            context.move(to: self.pieCenter!);
            context.addLine(to: chart.startPoint);
            context.addArc(center: self.pieCenter!, radius: self.radius!, startAngle: chart.startAngle, endAngle:chart.endAngle, clockwise: false);
            context.closePath();
            context.addRect(chart.keyColorRect);
            chart.color.setFill();
            
            context.drawPath(using: CGPathDrawingMode.fill);
            
            let string = NSMutableAttributedString();
            string.append(NSAttributedString(string: chart.key, attributes: [.font : self.configuration.keyValueFont, .foregroundColor : self.configuration.keyColor]));
            string.append(NSAttributedString(string: " ", attributes: [.font : self.configuration.keyValueFont, .foregroundColor : self.configuration.keyColor]));
            string.append(NSAttributedString(string: chart.valueString, attributes: [.font : self.configuration.keyValueFont, .foregroundColor : self.configuration.valueColor]));
            string.draw(in: chart.keyRect);
        }
    }
}
